﻿using UnityEngine;
using System.Collections.Generic;
using LuaFramework;
using webSocket;

public class SocketMgr : MonoBehaviour, WebSocketUnityDelegate {
    private WebSocketUnity webSocket;
    protected readonly object m_sync = new object();

    private bool isConnected = false;
    public bool IsConnected {
        get {
            return isConnected;
        }
    }
    void Awake() {
        DontDestroyOnLoad(this);
    }
    public void SendConnected() {
        if (!isConnected)
        {
            Debug.Log("[WebSocketMgr] 服务器连接地址: " + AppConst.WebSocketAddress);
            webSocket = new WebSocketUnity(AppConst.WebSocketAddress, this);
            webSocket.Open();
        }
        else
        {
            Debug.Log("[NetSocketMgr] 网络正在或已经链接");
        }
    }
    public void CloseSocket()
    {
        if (webSocket!=null)
        {
            webSocket.Close();
            Debug.Log("[SocketMgr] 连接断开");
            isConnected = false;
        }
    }
    public bool CheckNetOpen()
    {
        return webSocket.IsOpened();
    }
    public void Send(byte[] data) {
        if (data != null) {
            this.webSocket.Send(data);
        }
    }
    //  websocket is opened 的时候执行
    public void OnWebSocketUnityOpen(string sender) {
        lock (m_sync)
        {
            isConnected = true;
        }
        Debug.Log("[NetSocketMgr] WebSocket connected, " + sender);
    }
    public void OnWebScoketclose() {
        lock (m_sync)
        {
            isConnected = false;
        }
        webSocket.Close();
    }
    public void OnWebSocketUnityOnMessage(string sender) {
        Debug.Log("[NetSocketMgr] OnWebSocketUnityOnMessage");
    }
    // websocket is closed 的时候执行
    public void OnWebSocketUnityClose(string reason) {
        Debug.Log("WebSocket Close : " + reason);
        lock (m_sync)
        {
            isConnected = false;
        }
    }
    // websocket接收到 string 类型的message是执行
    public void OnWebSocketUnityReceiveMessage(string message) {
        Debug.Log("Received from server : " + message);
    }

    public void OnWebSocketUnityReceiveDataOnMobile(string base64EncodedData) {
        // it's a limitation when we communicate between plugin and C# scripts, we need to use string
        byte[] decodedData = webSocket.decodeBase64String(base64EncodedData);
        OnWebSocketUnityReceiveData(decodedData);
    }
    // This event happens when the websocket did receive data
    public void OnWebSocketUnityReceiveData(byte[] data)
    {
        WebSocketByteBuffer in0 = new WebSocketByteBuffer(data);
        int type = in0.readInt();
        int id = in0.readInt();
        NetworkManager.AddEvent(type * 10000 + id, in0);
        Debug.Log("[NetSocketMgr]addNetMsg: type:" + type + ",id: " + id);
    }
    // This event happens when you get an error@
    public void OnWebSocketUnityError(string error)
    {
        Debug.Log("[NetSocketMgr] socket error");
        lock (m_sync)
        {
            isConnected = false;
            onError = true;
        }
    }
    private bool lastState = false;
    private bool onError = false;
    private void Update()
    {
        lock (m_sync)
        {
            if (onError)
            {
                onError = false;
                AppFacade.Instance.GetManager<NetworkManager>(ManagerName.Network).OnSocketError();
            }
            if (isConnected != lastState)
            {
                lastState = isConnected;
                if (isConnected)
                    AppFacade.Instance.GetManager<NetworkManager>(ManagerName.Network).OnSocketConnect();
                else
                    AppFacade.Instance.GetManager<NetworkManager>(ManagerName.Network).OnSocketClose();
            }
        }
    }
    private void OnDestroy()
    {
        CloseSocket();
    }
}
